//
//  ChatRoomViewModel.swift
//  Chatup
//
//  Created by iron man on 2023/12/10.
//

import Foundation
import FirebaseAnalytics


@MainActor
class ChatRoomViewModel: ObservableObject{
    @Published var showDialog = false
    @Published var messages: [MessageModel] = []
    @Published var outputMsg = 0
    @Published var isVip = false
    @Published var leftCount = 5
    @Published var isEdit = false
    @Published var newUser = false
    @Published var showGpt3VipTips = false
    @Published var showGpt4VipTips = false
    @Published var resCount = 0
    @Published var quickItems: [WriteAssistansModel] = []
    @Published var choosed: TempModel = .init(name: "", id: 0, icon: "", des: "")
    @Published var roleList: [TempModel] = []
    var quickItemsTotal: [WriteAssistansModel] = []
    var tempStr = ""
    var alllist: [RoleModel] = []
    var logFrom = ""
    var curMessageIndex = 0
    var response = ""
    var currentRole: RoleModel?
    init() {
        logShowChatPage()

        isVip = UserDefaults.standard.bool(forKey: "kIsVip")
        if !Date.isToday() {
            leftCount = 5
            UserDefaults.standard.setValue(leftCount, forKey: "leftCount")
            UserDefaults.standard.synchronize()
            UserDefaults.standard.setValue(Double(Date().timeIntervalSince1970), forKey: "kSaveDate")
            UserDefaults.standard.synchronize()
        } else {
            leftCount = UserDefaults.standard.integer(forKey: "leftCount")
            if !isVip && leftCount == 0 {
                showGpt3VipTips = true
            }
        }

        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_1"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_2"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_3"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_4"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_5"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_6"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_7"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_8"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_9"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_10"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_11"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_12"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_13"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_14"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_15"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_16"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_17"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_18"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_19"), iconName: ""))
        quickItemsTotal.append(.init(name: String.i18nText("prompts_quick_response_20"), iconName: ""))
        if let list = selectSixUniqueItems(from: quickItems, in: quickItemsTotal) {
            quickItems = list
        }
    }

    func refreshProData() {
        if let list = selectSixUniqueItems(from: quickItems, in: quickItemsTotal) {
            quickItems = list
        }
    }

    func initData() {
        leftCount = UserDefaults.standard.integer(forKey: "leftCount")
        isVip = UserDefaults.standard.bool(forKey: "kWhetherVip")
        showGpt3VipTips = UserDefaults.standard.bool(forKey: "gpt3oversize")
        showGpt4VipTips = UserDefaults.standard.bool(forKey: "gpt4oversize")
    }
    
    func refreshVip() {
        leftCount = UserDefaults.standard.integer(forKey: "leftCount")
        isVip = UserDefaults.standard.bool(forKey: "kWhetherVip")
        if isVip{
            if showGpt3VipTips{
                showGpt3VipTips = false
            }
            if showGpt4VipTips{
                showGpt4VipTips = false
            }
        }
    }

    

    func selectSixUniqueItems(from listA: [WriteAssistansModel], in listB: [WriteAssistansModel]) -> [WriteAssistansModel]? {
        guard listB.count >= 3 else {
            return nil
        }

        var selectedItems: [WriteAssistansModel] = []

        while selectedItems.count < 3 {
            if let randomItem = listB.randomElement(), !selectedItems.contains(where: { $0.name == randomItem.name }) && !listA.contains(where: { $0.name == randomItem.name }) {
                selectedItems.append(randomItem)
            }
        }

        return selectedItems
    }

    func changeId(roleId: Int) {
        guard roleId != 0 else { return }
        
//        currentRole = RoleDataManager.share.getRole(roleId: roleId)
        if let role = RoleDataManager.share.getRole(roleId: roleId){
            let roles = RoleDataManager.share.getRoles(category: role.category)
            let rs : [TempModel] = roles.filter({ r in
                return role.id != r.id
            }).map({ r in
                return TempModel(name: r.name, id: r.id, icon: r.icon, des: r.i18nDesc())
            })
            roleList = Array(rs[0..<3])
        }
    
        if let role = RoleDataManager.share.getRole(roleId: roleId) {
            currentRole = role
            if let roleModel = currentRole {
                messages.removeAll()
                self.resCount = 0
        
                let models = MassageDataManager.share.getMsg(roleId: roleId)
                if models.count == 0 {
                    let msgModel = MsgModel(type: .bot, messageType: .text, message: roleModel.i18nGreeting(), roleId: roleModel.id, isLike: false, isUnlike: false)
                    self.saveMessage(msgs: [msgModel])
                    messages.append(.init(isUser: false, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: roleModel.icon, message: roleModel.i18nGreeting(), isFinish: true, isStart: false,roleId: String(roleId)))
                    if roleModel.images.count > 0 {
                        let imgModel = MsgModel(type: .bot, messageType: .image, message: roleModel.currentImage(), roleId: roleModel.id, isLike: false, isUnlike: false)
                        self.saveMessage(msgs: [imgModel])
                        messages.append(.init(isUser: false, messageType: .assetsImage, robotIcon: currentRole?.icon ?? "icon_robot", message: imgModel.message, isFinish: true, isStart: false,roleId: String(roleId)))
                    }
                    newUser = true
                } else {
                    newUser = false
                    models.forEach { msg in
                        if msg.type == .bot {
                            messages.append(.init(isUser: false, messageType: MessageType(rawValue: msg.messageType.rawValue) ?? .text, robotIcon: currentRole?.icon ?? "icon_robot", message: msg.message, isFinish: true, isStart: false,roleId: String(roleId)))
                        } else {
                            messages.append(.init(isUser: true, messageType: MessageType(rawValue: msg.messageType.rawValue) ?? .text, robotIcon: currentRole?.icon ?? "icon_robot", message: msg.message, isFinish: true, isStart: false,roleId: String(roleId)))
                        }
                    }
                    if messages.filter({ msg in
                        msg.isUser
                    }).count == 0 {
                        newUser = true
                    }
                }
                
            }
        }

        if let model = currentRole {
            choosed = .init(name: model.name, id: model.roleType, icon: model.icon, des: model.i18nDesc())
        }
    }

    func refreshUI(msg: String) {
        newUser = false
        if !isVip {
            leftCount = leftCount - 1
            UserDefaults.standard.setValue(leftCount, forKey: "leftCount")
            UserDefaults.standard.synchronize()
        }
        logChatSend()
        guard let currentRole = currentRole else { return }
        messages.append(.init(isUser: true, messageType: .text, robotIcon: "icon_robot", message: msg, isFinish: false, isStart: false,roleId: String(currentRole.serverId)))
     
        let msgModel = MsgModel(type: .user, messageType: .text, message: msg, roleId: currentRole.serverId, isLike: false, isUnlike: false)
        MassageDataManager.share.saveMsg(msg: msgModel)
        response = String.i18nText("chat_typing")
        messages.append(.init(isUser: false, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: currentRole.icon, message: response, isFinish: false, isStart: true, isOutputResponse: true,context: msg, roleId: String(currentRole.serverId)))
        outputMsg = outputMsg + 1
//        RequestManager.shared.postWithStream("https://backend.aichattings.com/api/v2/chatgpt/talk", params: params(msg: msg)) { _, code in
////            self.messages.last?.isFinish = true
//            if self.response.hasPrefix(String.i18nText("chat_typing")) {
//                self.logReceiveFailed(reason: "UnKnow:\(String(describing: code))")
//                self.outputMsg = 0
//                self.messages[self.messages.count - 1] = .init(isUser: false, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: currentRole.icon, message: String.i18nText("chat_wrong"), isFinish: true, isStart: false, isOutputResponse: false)
//                if !self.isVip {
//                    self.leftCount = self.leftCount + 1
//                    UserDefaults.standard.setValue(self.leftCount, forKey: "leftCount")
//                    UserDefaults.standard.synchronize()
//                }
//                return
//            }
//            self.logReceive()
//            if let lastModel = self.messages.last {
//                let newModel = MessageModel(isUser: lastModel.isUser, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: lastModel.robotIcon, message: lastModel.message, isFinish: true, isStart: false, isOutputResponse: false)
//                self.messages[self.messages.count - 1] = newModel
//            }
//            self.outputMsg = self.outputMsg + 1
//            self.resCount = self.resCount + 1
//            let msgModel = MsgModel(type: .bot, messageType: .text, message: self.response, roleId: self.currentRole!.id, isLike: false, isUnlike: false)
//            MassageDataManager.share.saveMsg(msg: msgModel)
//            /// 每五次互动聊天发一次图片
//            if self.resCount == 2 && self.currentRole?.images.count ?? 0 > 0{
//                self.resCount = 0
//                let imgModel = MsgModel(type: .bot, messageType: .image, message: self.currentRole?.currentImage() ?? "", roleId: self.currentRole!.id, isLike: false, isUnlike: false)
//                MassageDataManager.share.saveMsg(msg: imgModel)
//                self.currentRole?.imageIndex = (self.currentRole?.imageIndex ?? 1) + 1
//                RoleDataManager.share.updateRole(role:currentRole)
//                self.messages.append(.init(isUser: false, messageType: .assetsImage, robotIcon: currentRole.icon, message: imgModel.message, isFinish: false, isStart: false))
//                
//            }
//        } fail: { _, _, msg in
//            self.logReceiveFailed(reason: msg ?? "")
//            self.outputMsg = 0
//            self.messages[self.messages.count - 1] = .init(isUser: false, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: currentRole.icon, message: String.i18nText("chat_wrong"), isFinish: true, isStart: false, isOutputResponse: false)
//            if !self.isVip {
//                self.leftCount = self.leftCount + 1
//                UserDefaults.standard.setValue(self.leftCount, forKey: "leftCount")
//                UserDefaults.standard.synchronize()
//            }
//        } reading: { str in
////            print("testJJ-2-:\(str)")
//            self.tempStr.append(str)
//            if self.tempStr.count > 5 {
//                self.outputMsg = self.outputMsg + 1
//                self.tempStr = ""
//            }
//            var strIn = str
//            if strIn == "" {
//                strIn = "\n\n"
//                self.outputMsg = self.outputMsg + 1
//            }
////            if strIn.hasPrefix(" ") {
////                strIn = "\n"+strIn
////                self.outputMsg = self.outputMsg + 1
////            }
//            if self.response.hasPrefix(String.i18nText("chat_typing")) {
//                self.response = strIn
//            } else {
//                self.response.append(strIn)
//            }
//            self.messages[self.messages.count - 1] = .init(isUser: false, messageType: MessageType(rawValue: msgModel.messageType.rawValue) ?? .text, robotIcon: currentRole.icon, message: self.response, isFinish: false, isStart: false, isOutputResponse: true)
//        }
    }
    
//    let msgModel = MsgModel(type: .bot, messageType: .text, message: roleModel.greeting, roleId: roleModel.id, isLike: false, isUnlike: false)
//    let imgModel = MsgModel(type: .bot, messageType: .image, message: "icon_icon2", roleId: roleModel.id, isLike: false, isUnlike: false)
//    MassageDataManager.share.saveMsgs(msgs: [msgModel, imgModel])
    private func saveMessage(msgs:[MsgModel]) {
        
        guard curMessageIndex < msgs.count else {
            return
        }

        let msg = msgs[curMessageIndex]
        MassageDataManager.share.saveMsg(msg: msg)
                
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            self.curMessageIndex += 1
            self.saveMessage(msgs: msgs)
        }
    }


    private func combineStr(msg: String) -> String {
        let uuid = UserDefaults.standard.string(forKey: "uuid")
        let roleId = currentRole?.roleType
        var str = "msg=".appending(msg)
        if let uid = uuid {
            str.append("&uuid=\(uid)")
        }
        if let id = roleId {
            str.append("&role_id=\(id)")
        }
        return str
    }

    private func params(msg: String) -> [String: String]? {
        guard let uuid = UserDefaults.standard.string(forKey: "uuid"), let roleId = currentRole?.roleType else { return nil }
        return ["msg": msg,
                "uuid": uuid,
                "role_id": String(roleId),
                "model": "gpt3",
                "ep_user_id": UserDefaults.standard.string(forKey: "ep_user_id") ?? "1",
                "endpoint": "ios"]
    }
    
    func addLocalMessage(m:MsgModel){
        messages.append(.init(isUser: false, messageType: .assetsImage, robotIcon: currentRole?.icon ?? "", message: m.message, isFinish: true, isStart: false, isOutputResponse: true,roleId: String(m.roleId)))
    }
}


extension ChatRoomViewModel {
    func logShowChatPage() {
        Analytics.logEvent("characters_chat_page_show", parameters: nil)
    }

    func logChatSend() {
        Analytics.logEvent("chat_sent", parameters: nil)
    }

    func logReceive() {
        Analytics.logEvent("chat_received", parameters: nil)
    }

    func logReceiveFailed(reason: String) {
        Analytics.logEvent("chat_receive_failed", parameters: ["error": reason])
    }

    func logClickCharaters() {
        Analytics.logEvent("chat_characters", parameters: nil)
    }

    func logSwitchCharaters(role_id: String) {
        Analytics.logEvent("characters_chat_page_click", parameters: ["role_id": role_id])
    }

    func logCreditsClick(role_id: String) {
        Analytics.logEvent("characters_chat_page_credits_click", parameters: ["role_id": role_id])
    }

    func logBannerClick(role_id: String) {
        Analytics.logEvent("characters_chat_page_banner_click", parameters: ["role_id": role_id])
    }
    

    func logPicClick(role_id: String) {
        Analytics.logEvent("characters_chat_page_pic_click", parameters: ["role_id": role_id])
    }

    func logFreeClick(role_id: String) {
        Analytics.logEvent("characters_chat_free_click", parameters: ["role_id": role_id])
    }
}
